home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PrinterFonts.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains for the Font Handler code
- for building printer font lists.
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1991-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include <Collections.h>
- #include <MacMemory.h>
- #include <String.h>
- #include "GXToPSBuildConfig.h"
- #include <GXExceptions.h>
- #include "IOUtilities.h"
- #include "GXPrintingUniverse.h"
-
- #include "FontDatabase.h"
- #include "FontHandler.h"
- #include "FontHandlerPrivate.h"
- #include "FontHandlerVariations.h"
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
- #define sizeField(structure, field) sizeof( ((structure *)0)->field )
- #define sizeArray(type, length) ( (long) &((type *)0)[length] )
- #define offsetField(type, field) ( (long) &((type *)0)->field )
-
- #define Exchange(a, b) { register long temp = (a); (a) = (b); (b) = temp; }
- #define SwapType(type, a, b) { register type temp = (a); (a) = (b); (b) = temp; }
-
-
- //<FF>
- /********************************************
-
- Function: FHMarkSEACPositions
-
- Function marks the positions in the encoding
- with the 0xFFFE sentinal value that says
- leave for SEAC encoding. Having this value
- in there will prevent me from using it as an
- encoding position for a downloaded font.
-
- mark: Boolean, true to initially mark to
- avoid using
- false to unmark so encoding is valid.
-
- *********************************************/
- void FHMarkSEACPositions(gxFont theFont, unsigned short *encoding, Boolean mark );
- void FHMarkSEACPositions(gxFont theFont, unsigned short *encoding, Boolean mark )
- {
- long index;
- gxFontFormatTag fontFormat;
-
- unsigned short SEAC_CODES [] = {
-
- /* STD_A */ 0x41,
- /* STD_C */ 0x43,
- /* STD_E */ 0x45,
- /* STD_I */ 0x49,
- /* STD_N */ 0x4E,
- /* STD_O */ 0x4F,
- /* STD_S */ 0x53,
- /* STD_U */ 0x55,
- /* STD_Y */ 0x59,
- /* STD_Z */ 0x5A,
-
- /* STD_a */ 0x61,
- /* STD_c */ 0x63,
- /* STD_e */ 0x65,
- /* STD_i */ 0x69,
- /* STD_n */ 0x6E,
- /* STD_o */ 0x6F,
- /* STD_s */ 0x73,
- /* STD_u */ 0x75,
- /* STY_y */ 0x79,
- /* STD_z */ 0x7A,
-
- /* STD_acute */ 0xC2,
- /* STD_caron */ 0xCF,
- /* STD_cedilla */ 0xCB,
- /* STD_circumflex */ 0xC3,
- /* STD_dieresis */ 0xC8,
- /* STD_grave */ 0xC1,
- /* STD_ring */ 0xCA,
- /* STD_tilde */ 0xC4,
- /* STD_dotlessi */ 0xF5
-
- };
-
- fontFormat = GXGetFontFormat(theFont);
-
- if (fontFormat == 'typ1') {
-
- if (GXCountFontGlyphs(theFont) > 0x0000FFFE) {
-
- #if DEBUGLEVEL > 0
- dprintf(notrace, "Can't guarantee SEAC with font that has over 65534 glyphs");
- #endif
-
- } else {
-
- long count = sizeof(SEAC_CODES) / sizeof(unsigned short);
-
- /** Mark all of the positions in the encoding for SEAC **/
-
- for (index = 0; index < count; ++index)
- if (mark)
- encoding[ SEAC_CODES[index] ] = 0xFFFE;
- else
- encoding[ SEAC_CODES[index] ] = 0xFFFF;
-
- }//end if
-
- }//end if
-
- }//FHMarkSEACPositions
-
-
-
- //<FF>
- /***************************************
-
- Function builds the glyph to character mapping for using printer resident composite fonts
-
- ****************************************/
- OSErr FHMakeGlyphToCharMap(TPrinterFontRec *printerFont);
- OSErr FHMakeGlyphToCharMap(TPrinterFontRec *printerFont)
- {
- OSErr status = kNoPOSTtable4;
- gxFont theFont = printerFont->theRealFont;
-
-
- #define postscriptTableTag 0x706f7374 /* 'post' */
-
- long tableindx;
- long tablesize;
-
- if( ( tablesize = GXFindFontTable( theFont, postscriptTableTag, nil, &tableindx ) ) && tableindx ) {
-
- /* the following definitions fromt the truetpe scaler file 'truetype types.h' */
-
- struct postTableHeader {
- Fixed version;
- Fixed italicAngle;
- short underlinePosition;
- short underlineThickness;
- short isFixedPitch;
- short pad;
- unsigned long minMemType42;
- unsigned long maxMemType42;
- unsigned long minMemType1;
- unsigned long maxMemType1;
-
- unsigned short data[];
-
- };
-
- long version;
-
- /** The data in the post table 4 is the glyph code to character code mapping **/
-
- if( GXGetFontTableParts( theFont, tableindx, 0, sizeof( version ), &version, nil )
- && ( version == 0x40000 ) ) {
-
- Handle dataHdl;
- unsigned short *dataPtr;
- long count = GXCountFontGlyphs(theFont);
-
- // time to load in the whole table
-
- status = PrNewHandle(&dataHdl, sizeof(unsigned short) * count );
- nrequire(status, failed_newHandle);
-
- HLock( dataHdl );
- dataPtr = * (unsigned short **) dataHdl;
-
- (void) GXGetFontTableParts( theFont, tableindx, offsetField( struct postTableHeader, data ),
- sizeof( unsigned short ) * count, dataPtr, nil );
-
- HUnlock( dataHdl );
-
- printerFont->glyphToCharCodeMap = dataHdl;
-
- }//end if
-
-
- }//end if
-
- #undef postscriptTableTag
-
- failed_newHandle:
- return(status);
-
- }//FHMakeGlyphToCharMap
-
-
-
- //<FF>
- /********************************************
-
- Function: FHAddGlyphHash
-
- Function finds an empty spot in the hash table
- for a glyph code. Adds glyph ID to hash table.
-
- glyphIndex: the index to hash.
- printerCodes: the hash table array.
-
- Hash function is index % 256,
- simple linear probe collision resolution.
-
- Function returns whether or not there was room in the
- table.
-
- *********************************************/
- Boolean FHAddGlyphHash(long glyphIndex, unsigned short *printerCodes);
- Boolean FHAddGlyphHash(long glyphIndex, unsigned short *printerCodes)
- {
- register long hashValue;
- register unsigned short *entry;
- Boolean wrappedAround = false;
- Boolean hadRoom = true;
-
- hashValue = glyphIndex & 0x000000FF; // index % 256.
-
- entry = printerCodes + hashValue; // Get a pointer into the table.
-
- if (*entry != fhSentinalGlyphCode) { // Was there a collision?
-
- if (++hashValue >= 256) { // advance to next position, do we have to wrap around?
-
- hashValue = 0;
- wrappedAround = true;
-
- }//end if
-
- entry = printerCodes + hashValue; // Get the pointer again.
-
- while (true) { // Yes, resolve collision.
-
- if (*entry != fhSentinalGlyphCode) {
-
- ++hashValue;
- ++entry;
-
- if (hashValue >= 256) { // wrap around if necessary.
-
- if (wrappedAround) {
-
- hadRoom = false;
- break;
-
- }//end if
-
- hashValue = 0;
- entry = printerCodes;
-
- wrappedAround = true;
-
- }//end if
-
- } else {
-
- break; // found an open entry.
-
- }//end if
-
- }//end while
-
-
- }//end if
-
- if (hadRoom)
- *entry = glyphIndex;
-
- return(hadRoom);
-
- }//FHAddGlyphHash
-
-
-
- /********************************************
-
- Function: FHGetGlyphHash
-
- Function Returns printer code to use for the glyph index.
-
- glyphIndex: The glyph index.
- printerCodes: the hash table array.
-
- Hash function is index % 256,
- simple linear probe collision resolution.
-
- *********************************************/
- unsigned short FHGetGlyphHash(long glyphIndex, unsigned short *printerCodes)
- {
- register long hashValue;
- register unsigned short *entry;
- #if DEBUGLEVEL > 1
- Boolean wrappedAround = false;
- #endif
-
- hashValue = glyphIndex & 0x000000FF; // index % 256.
-
- entry = printerCodes + hashValue; // Get a pointer into the table.
-
- if (*entry != glyphIndex) { // First hash didn't find it?
-
- if (++hashValue >= 256) { // do we have to wrap around?
-
- hashValue = 0;
-
- #if DEBUGLEVEL > 1
- wrappedAround = true;
- #endif
-
- }//end if
-
- entry = printerCodes + hashValue; // Get the pointer again.
-
- while (true) { // try to find it.
-
- if (*entry != glyphIndex) {
-
- ++hashValue;
- ++entry;
-
- if (hashValue >= 256) { // wrap around if necessary.
-
- #if DEBUGLEVEL > 1
- if (wrappedAround) {
- dprintf(notrace, "Couldn't find glyph %X in hash table, fatal error", glyphIndex);
- dprintf(notrace, "Hash table: %X", printerCodes);
- break;
- }
- #endif
-
- hashValue = 0;
- entry = printerCodes;
- #if DEBUGLEVEL > 1
- wrappedAround = true;
- #endif
-
- }//end if
-
- } else {
-
- break; // found match.
-
- }//end if
-
- }//end while
-
-
- }//end if
-
- return(hashValue); // The index of the entry, this will be the printer code to use.
-
- }//FHGetGlyphHash
-
-
-
- //<FF>
- /********************************************
-
- Function: FHMakePrinterGlyphEncoding
-
- Function makes the encoding hash tables and usage arrays
- for a printer font record. If for a downloaded font
- pass nil for the fontLocation pointer.
-
- numGlyphs: Number of glyphs in the system font.
- docGlyphBits: Document glyph usage array.
- printerFont: A printer font record pointer.
- fontLocation: A printer font glyph location record. (Pass nil for encoding downloaded font)
- start: Starting glyph index to encode. Last Glyph encoded returned here.
- Start at this glyph for next font encoding for the printer-resident fonts.
- numEncoded: returned: number of glyphs encoded in this font.
- fdbFlags: font database flags for this font.
- doResidentGlyphs: pass true if making encoding for resident glyphs, false for downloaded glyphs
-
- returns: Boolean indicating that we tried to add glyphs into the hash table, but couldn't because
- it was full, indicating we need another printer font. This is slightly deceptive
- parameter name in that when being called with doResidentGlyphs=true, needMoreFonts
- will return true if we needed more printer-fonts to encode all of the resident glyphs.
- in the doResidentGlyphs=false case, it returns true if we need more printer-fonts
- to encode all of the document glyphs we need to download.
-
- *********************************************/
- Boolean FHMakePrinterGlyphEncoding(long numGlyphs, unsigned long *docGlyphBits,
- TPrinterFontRec *printerFont, gxPrinterGlyphsRec *fontLocation,
- long *start, long *numEncoded, Boolean doResidentGlyphs,
- TfdbInfoFlags fdbFlags, OSErr *status);
- Boolean FHMakePrinterGlyphEncoding(long numGlyphs, unsigned long *docGlyphBits,
- TPrinterFontRec *printerFont, gxPrinterGlyphsRec *fontLocation,
- long *start, long *numEncoded, Boolean doResidentGlyphs,
- TfdbInfoFlags fdbFlags, OSErr *status)
- {
- long glyphCount; // Counter for printer font glyphs.
- unsigned long mask; // Bit testing mask.
- unsigned long *nextResLong; // Long o'bits for traversing resident glyph bits.
- unsigned long *nextDocumentLong; // Long o'bits for traversing document glyph bits.
- unsigned long *nextUsageLong; // Long o'bits to mark glyph usage.
- Boolean needMoreFonts=false; // Do we need more fonts for this resident/doc font combo?
- long num = 0;
- long addGlyph; // Add this glyph to the encoding?
- Boolean compositeFont; // Are we working with a composite font on the printer?
-
- *status = noErr;
-
- compositeFont = (fontLocation->platform != gxGlyphPlatform) ? true : false;
- if (!doResidentGlyphs)
- compositeFont = false; // downloaded fonts are never composite fonts to start out with. (Can become later)
-
- /******** Point into bit arrays for first glyph being asked for ***************/
-
- mask = 0x80000000U >> (*start & 0x0000001F); // Initialize mask: start MOD 32 bit set.
- {
- long bitArrayOffset = *start >> 5; // Get start DIV 32.
-
- nextResLong = fontLocation->glyphBits + bitArrayOffset; // point into bit arrays.
- nextUsageLong = printerFont->glyphUsage + bitArrayOffset;
- nextDocumentLong = docGlyphBits + bitArrayOffset;
-
- }
-
- if ( !compositeFont && (fdbFlags & fdbUseMac8Bit) ) {
-
- /*** If we are supposed to use standard mac 8 bit encoding ***/
-
- unsigned short *aGlyphCode;
-
- /** if we are encoding for resident font, make sure there are resident glyphs **/
-
- if (!doResidentGlyphs || CountGlyphBits(fontLocation->glyphBits, numGlyphs)) {
-
- num = MakeMac8BitEncoding(printerFont->theRealFont, printerFont->printerFontCodes);
- check(num == 256);
-
- /** Set all bits in glyph usage array for this encoding **/
- aGlyphCode = printerFont->printerFontCodes;
- for (glyphCount = 0; glyphCount < 256; ++glyphCount) {
-
- if (*aGlyphCode <= numGlyphs) {
-
- BITSET(nextUsageLong, *aGlyphCode);
-
- } else {
-
- #if DEBUGLEVEL > 1
- dprintf(trace, "asked to encode glyph: %d, outside of font's range of %d", *aGlyphCode, numGlyphs);
- #endif
-
- }//end if
-
- ++aGlyphCode;
-
- }//end for
-
- } else {
-
- /*****
- We couldn't encode any glyphs because we were asked for resident
- encoding but the font needs to be downloaded
- *****/
- num = 0;
-
- }//end if
-
- } else {
-
- /****
- Make hash table encoding:
- Encode as many glyphs as we can from starting glyph through end.
- Stop when all glyphs have been encoded or hash table is full.
- *****/
-
- /* resereve SEAC positions if necessary */
- if (!compositeFont)
- FHMarkSEACPositions(printerFont->theRealFont, printerFont->printerFontCodes, true );
-
- for (glyphCount = *start; glyphCount < numGlyphs; ++glyphCount) {
-
- if (doResidentGlyphs)
- /** If printer font contains this glyph and doc requires it, encode it. **/
- addGlyph = (mask & *nextResLong & *nextDocumentLong);
- else
- /** If doc requires this glyph, and it is not a resident glyph encoded it. **/
- addGlyph = (mask & *nextDocumentLong & (~*nextResLong));
-
- if (addGlyph) {
-
- /** If it is a composite font or we had room in the encoding, add it to the printer font **/
- if (compositeFont || FHAddGlyphHash(glyphCount, printerFont->printerFontCodes)) {
-
- *nextUsageLong |= mask; // Set the usage bit for this printer font.
- ++num;
-
- } else { /*** There wasn't room for more glyphs, return that we need more fonts ***/
-
- *start = glyphCount; // update starting glyph for next time.
- needMoreFonts = true;
- break; // break out.
-
- }//end if
-
- }//end if
-
- /** Advance the mask and pointer **/
- if ( !(mask >>= 1) ) {
-
- mask = 0x80000000;
-
- ++nextResLong;
- ++nextUsageLong;
- ++nextDocumentLong;
-
- }//end if
-
- }//end for
-
- /* Unmark reserved SEAC positions */
- if (!compositeFont)
- FHMarkSEACPositions(printerFont->theRealFont, printerFont->printerFontCodes, false );
-
- }//end if
-
- /** Make the glyph to character map if necessary **/
- if (compositeFont && (num > 0)) {
-
- printerFont->info |= fontCantBeRencoded;
- *status = FHMakeGlyphToCharMap(printerFont);
- nrequire(*status, failed_glyphToChar);
-
- }//end if
-
- *numEncoded = num;
-
- failed_glyphToChar:
- return(needMoreFonts);
-
- }//FHMakePrinterGlyphEncoding
-
-
-
- //<FF>
- /********************************************
-
- Function FHNewPrinterFont:
-
- Function grows the FHRec handle to hold another
- printer font record, and returns a pointer to that
- record.
-
- hFHRec: The font handler context handle.
- theFont: The snapshot font reference for this printer font.
- printerFontIndex: The index of this printer font.
- usageSize: how many bytes for the glyph usage array (long alligned)
- printerFont: returned: Pointer into the hFHRec for this printer font entry.
- offset: returned: Offset into record for this printer font entry.
-
- **********************************************/
- OSErr FHNewPrinterFont(TFontHandlerHdl hFHRec, fhFont theFont, long printerFontIndex, long usageSize, TPrinterFontRec* *printerFont, long *offset);
- OSErr FHNewPrinterFont(TFontHandlerHdl hFHRec, fhFont theFont, long printerFontIndex, long usageSize, TPrinterFontRec* *printerFont, long *offset)
- {
- OSErr status;
- long size, oldSize;
- TFontHandlerPtr pFHRec;
- long nameLen;
- long index;
- gxFont theRealFont;
- long dbIndex;
- TPrinterFontRec *thePrinterFont;
-
- theRealFont = FHGetSnapShotFont(hFHRec, theFont, &dbIndex);
- check(theRealFont);
-
- /* Grow the font handler record */
-
- oldSize = sizeof(TFontHandlerRec) + (*hFHRec)->nextOffset;
- size = sizeof(TPrinterFontRec) + usageSize;
- nrequire(status = PrSetHandleSize((Handle)hFHRec, oldSize + size), failed_SetSize);
-
- pFHRec = *hFHRec;
- thePrinterFont = (TPrinterFontRec*)(pFHRec->printerFonts + pFHRec->nextOffset);
- *offset = pFHRec->nextOffset;
- pFHRec->nextOffset += size;
-
-
- thePrinterFont->usageSize = usageSize;
- thePrinterFont->nameIndex = kNoSuchFontName; // no cache on font name index yet.
- thePrinterFont->info = fontNotAvailable; // unknown information.
-
- /** Cache the font reference and index even though they are the tag and ID in the collection **/
-
- thePrinterFont->theFont = theFont; // Cache the snapshot font reference in here.
- thePrinterFont->prFontIndex = printerFontIndex; // Cache the index in here.
- thePrinterFont->theRealFont = theRealFont; // Cache the actual gx font reference here.
- thePrinterFont->dbIndex = dbIndex; // Cache this here, it helps us make names later.
-
- /***
- Cache the index of the PostScript name:
- If we find a name, cache the index,
- else index will remain -1 as initialized
- ***/
-
- nameLen = GXFindFontName(theRealFont, gxPostscriptFontName, gxMacintoshPlatform, gxNoScript, gxNoLanguage, nil, &index);
- if (nameLen > 0)
- thePrinterFont->nameIndex = index;
-
- /** Initialize printer codes to fhSentinalGlyphCode and glyph usage bits to 0 **/
-
- memset(thePrinterFont->glyphUsage, 0, usageSize); // usageSize is size of glyph bits.
- {
- short idx;
- unsigned short *p;
- p = thePrinterFont->printerFontCodes;
- for (idx = 255; idx >= -1; --idx)
- *p++ = fhSentinalGlyphCode;
- }
-
- thePrinterFont->glyphToCharCodeMap = nil; // no handle for mapping glyphs to chars.
-
- *printerFont = thePrinterFont;
-
- failed_SetSize:
- return(status);
-
- }//FHNewPrinterFont
-
- //<FF>
- /************************************************
-
- Function: FHAddPrinterFont.
-
- Function adds the required collection items for the
- printer font. Also increments the count of printer fonts.
-
- hFHRec: font handler record handle.
- theFont: the font reference.
- index: Index of prnter font.
- flags: printer font flags.
- offset: Offset off of printerFonts field of font handler record.
-
- **************************************************/
- OSErr FHAddPrinterFont(TFontHandlerHdl hFHRec, fhFont theFont, long index, long flags, long offset);
- OSErr FHAddPrinterFont(TFontHandlerHdl hFHRec, fhFont theFont, long index, long flags, long offset)
- {
- OSErr status;
-
- status = AddCollectionItem((*hFHRec)->printerFontsOffsets,
- (CollectionTag)theFont,
- index,
- 4,
- &offset);
- nrequire(status, failed_AddItem);
-
- status = SetCollectionItemInfo((*hFHRec)->printerFontsOffsets,
- (CollectionTag)theFont,
- index,
- kCollectionUserAttributes,
- flags);
- nrequire(status, failed_AddItemInfo);
-
- (*hFHRec)->numPrFonts += 1;
-
- failed_AddItemInfo:
- failed_AddItem:
-
- return(status);
-
- }//FHAddPrinterFont
-
- //<FF>
- /****************************************
-
- Function: FHAddPrinterFonts:
-
- Function takes a document font and adds
- all required printer font entries to the list.
-
- hFHRec: a font handler context handle.
- theFont: font ID of font to add printer fonts for.
- glyphBits: Pointer to the glyph bits for the document font.
- nGlyphs: number of total glyphs in document font.
- fontFlags: font flags from font database.
-
- *****************************************/
- OSErr FHAddPrinterFonts(TFontHandlerHdl hFHRec, fhFont theFont, unsigned long *glyphBits, long nGlyphs, TfdbInfoFlags fdbFlags)
- {
- OSErr status;
- long glyphsUsed; // Number of glyphs used in doc.
- gxPrinterGlyphsRec *fontLocation; // A printer glyph location.
- long glyphBitsSize; // size of bit arrays.
- long docFontFlags = 0;
- gxFont theRealFont; // The actual gx font reference for this fhFont.
- TPrinterFontRec *printerFont; // A printer font record.
- long startGlyph; // Glyph to start encoding a printer font at.
- long offset, printerFontIndex;
- Boolean needMoreFonts; // Do we still need more printer fonts for the doc font?
- Boolean canUse; // Can the font be downloaded?
- long size;
- long vmSize; // VM Size of the printer font.
- long glyphsEncoded, totalGlyphsEncoded;
- Handle workHandle;
- long dbIndex;
-
- //dprintf(trace, "Adding printer fonts for font: %d", theFont);
-
- glyphsUsed = CountGlyphBits(glyphBits, nGlyphs);
-
- /** Initialize the font to be excluded from the prerequisite list **/
- /** A font only needs to be included if we are downloading it **/
-
- theRealFont = FHGetSnapShotFont(hFHRec, theFont, nil);
- status = FontDbaseExcludePrerequisite((*hFHRec)->docDbase, theRealFont, true);
- nrequire(status, failed_exclude);
-
- /******* Get printer information for this font ******/
-
- /** First make sure workspace is big enough **/
-
- glyphBitsSize = 4 * ( ( nGlyphs + 31 ) / 32 );
- size = sizeof(gxPrinterGlyphsRec) - sizeof (unsigned long) + glyphBitsSize;
- status = FHSetWorkHandleSize(hFHRec, size, 0, &workHandle);
- nrequire(status, failed_SetSize);
-
- HLock(workHandle);
- fontLocation = (gxPrinterGlyphsRec*)*workHandle;
- memset(fontLocation, 0, size); // clear it so message can set bits for glyph usage.
- fontLocation->theFont = FHGetSnapShotFont(hFHRec, theFont, &dbIndex);
- fontLocation->nGlyphs = nGlyphs;
-
- /** Get the printer info for the font **/
-
- status = (*hFHRec)->psDevice->GetPrinterGlyphsInformation(fontLocation); // DL 7/27/97: Used to use GX message, now device method.
- nrequire(status, failed_GetFontGlyphs);
-
-
- /*** Build the entries for the printer resident glyphs ***/
-
- startGlyph = 0;
- totalGlyphsEncoded = 0;
- needMoreFonts = true;
-
- /**********
- Find the index to start at for building printer fonts:
- If there are currently no entries for the given font then
- start at zero (this will be the case at doc-setup, but not
- necessarily the case for fonts added during imaging time.
-
- The starting index is the number of printer fonts so far
- since the indecies are zero-based.
- **********/
- printerFontIndex = CountTaggedCollectionItems((*hFHRec)->printerFontsOffsets, (CollectionTag)theFont);
-
- /*****************************
-
- Loop makes printer font records of up to 256 (except for printer resident composite fonts)
- glyphs per record for all of the glyphs that
- are contained in the resident font and required
- by the document.
-
- Loop terminates when the whole document glyph
- set is consumed by printer font records.
-
- ******************************/
-
- while (needMoreFonts) { /** Do while we still need another printer font **/
-
- /** Make printer font record for next set of glyphs **/
-
- status = FHNewPrinterFont(hFHRec, theFont, printerFontIndex, glyphBitsSize, &printerFont, &offset); // Warning, if memory moves printerFont invalidates.
- nrequire(status, failed_NewPrinterFont);
-
- printerFont->docVMUsage = 0; // Nothing to download.
- printerFont->vmUsage = kEncodingOverhead; // memory used is just for encoding.
- printerFont->usageSize = glyphBitsSize;
-
- /** Generate the encoding **/
-
- HLockHi((Handle)hFHRec); // we don't want printerFont to move
- printerFont = (TPrinterFontRec*)((*hFHRec)->printerFonts + offset); // Point to it again.
-
- needMoreFonts = FHMakePrinterGlyphEncoding(nGlyphs, glyphBits, printerFont, fontLocation,
- &startGlyph, &glyphsEncoded, true, fdbFlags, &status);
- nrequire(status, failed_MakeEncoding);
-
- HUnlock((Handle)hFHRec);
-
- /** Add the collection item for this printer font **/
-
- if (glyphsEncoded > 0) {
-
- printerFont->info |= fontIsInPrinter; // We encoded some glyphs, mark as resident.
-
- status = FHAddPrinterFont(hFHRec, theFont, printerFontIndex, docFontFlags, offset);
- nrequire(status, failed_AddPrinterFont);
-
- /** printerFont is now invalid pointer because FHAddPrinterFont could move memory **/
-
- ++printerFontIndex;
-
- totalGlyphsEncoded += glyphsEncoded;
-
- }//end if
-
- }//end while;
-
- /************************************************
- Given the number of glyphs required by the document
- that are printer resident and the rest of our global
- information (such as printer type) see if it makes
- sense to go ahead and do font downloading, or mark
- the fontCantBeUsed flag on the printer font for all
- glyphs.
- *************************************************/
- status = FHTestFontCanBeUsed(hFHRec, theFont, glyphsUsed, glyphsEncoded, &canUse);
- nrequire(status, failed_testFont);
- if ( !canUse ) {
-
- printerFont = (TPrinterFontRec*)((*hFHRec)->printerFonts + offset); // repoint to record in cased mem moved.
- printerFont->info |= fontCantBeUsed;
- printerFont->usageSize = 0;
-
- /*****
- Set total encoded to be number of glyphs in font,
- this will ensure that we don't try to encode any of
- these glyphs for downloading to the printer. Also,
- set all of the glyph bits in this printer font record
- so we always get a hit without searching.
- *****/
- totalGlyphsEncoded = glyphsUsed;
- memset(printerFont->glyphUsage, 0xFF, glyphBitsSize);
-
- /** Add collection item for this font **/
- status = FHAddPrinterFont(hFHRec, theFont, printerFontIndex, docFontFlags, offset);
- nrequire(status, failed_AddPrinterFont);
-
- }//end if
-
- /************************************************
- If there were any glyphs required by the document
- that are not in the printer, make downloaded printer
- fonts for them. Code is mostly same as above.
- Except that glyphs are guarenteed to be encoded
- because there is no dependancy on printer resident glyphs.
- *************************************************/
-
- if ( glyphsUsed > totalGlyphsEncoded) {
-
- /** If we are creating a font for downloading, make sure it is included for prerequisites **/
-
- status = FontDbaseExcludePrerequisite((*hFHRec)->docDbase, theRealFont, false);
- nrequire(status, failed_excludeFalse);
-
- /**********
- Compute the size of the document font excluding any glyphs already in the printer
- Note, this function uses workHandle[1] so make sure it is not in use during this call.
- Also, this call will move memory.
- **********/
-
- status = FHComputeDocFontSize(hFHRec, theFont, nGlyphs, glyphBits, fontLocation->glyphBits, &vmSize);
- nrequire(status, failed_ComputeSize);
-
- /** encode the rest of the glyphs **/
-
- needMoreFonts = true;
- startGlyph = 0;
- while (needMoreFonts) { /** Do while we still need another printer font **/
-
- /**********
- Only allocate a new printer font record if the one allocated for resident glyphs was
- used (some of the glyphs needed by doc are resident on printer). If not, then the
- one allocated above is empty and we can use it.
- ***********/
- if (totalGlyphsEncoded > 0) {
-
- status = FHNewPrinterFont(hFHRec, theFont, printerFontIndex, glyphBitsSize, &printerFont, &offset); // Warning, if memory moves printerFont invalidates.
- nrequire(status, failed_NewPrinterFont);
-
- } else {
-
- /** Just use the printer font that was allocated before but recalculate pointer in case memory moved **/
- printerFont = (TPrinterFontRec*)((*hFHRec)->printerFonts + offset);
-
- }//end if
-
- printerFont->usageSize = glyphBitsSize; // size of the bit array.
-
- /** Make printer font record for next set of glyphs **/
-
- HLockHi((Handle)hFHRec); // we don't want printerFont to move
- printerFont = (TPrinterFontRec*)((*hFHRec)->printerFonts + offset);
-
- needMoreFonts = FHMakePrinterGlyphEncoding(nGlyphs, glyphBits, printerFont, fontLocation,
- &startGlyph, &glyphsEncoded, false, fdbFlags, &status);
-
- nrequire(status, failed_MakeEncoding);
- HUnlock((Handle)hFHRec);
-
- if (glyphsEncoded > 0) {
-
- totalGlyphsEncoded += glyphsEncoded;
-
- /** Compute the vm usage of this printer font **/
-
- HLockHi((Handle)hFHRec); // lock it down and re-point to the printer font record.
- printerFont = (TPrinterFontRec*)((*hFHRec)->printerFonts + offset);
-
- /** Compute the sizes for this printer font **/
- printerFont->docVMUsage = vmSize; // size of font for all document glyphs
- status = FHComputePrinterFontSize(hFHRec, printerFont); // Size for just these glyphs.
- nrequire(status, failed_ComputePrSize);
-
- HUnlock((Handle)hFHRec); // unlock it in for allocation of new printer fonts.
-
- /** Add the collection item for this printer font **/
-
- status = FHAddPrinterFont(hFHRec, theFont, printerFontIndex, docFontFlags, offset);
- nrequire(status, failed_AddPrinterFont);
-
- ++printerFontIndex;
-
- }//end if
-
- #if DEBUGLEVEL > 1
- if (glyphsEncoded == 0) {
- status = -9999;
- DebugStr("\pSomehow no glyphs were encoded in downloadable font - This is a bug");
- goto failed_AddPrinterFont;
- }//end if
- #endif
-
- }//end while
-
- }//end if
-
- failed_ComputePrSize:
- failed_ComputeSize:
- failed_excludeFalse:
- failed_testFont:
- failed_AddPrinterFont:
- failed_MakeEncoding:
- failed_NewPrinterFont:
- failed_GetFontGlyphs:
-
- FHReleaseWorkspace(hFHRec, 0);
-
- failed_SetSize:
- failed_exclude:
-
- return(status);
-
- }//FHAddPrinterFonts
-